<!-- 
  reactive()
    接受一个对象类型的参数，返回一个代理对象，是响应式的数据

      PS: 
        1. 推荐在要将对象类型的数据做响应式的时候，使用 reactive，其余情况都推荐 ref
        2. 不要对 reactive 返回值直接做修改，会丢失响应式
        3. ref 的自动解包，当 reactive 数据中某个属性的值是一个 ref 数据的时候，我们在使用它时无需 .value
          注意，如果 reactive 数据是个 数组或Map的话，他们里面的 ref 数据在获取的时候不会自动解包

  ref()
    接受一个基本数据类型的参数，返回一个响应式数据。该响应式数据中会有一个 value 属性指向原始值。

      PS: 
        1. ref() 也可以接受一个 对象类型的数据做为参数，它内部会使用 reactive 对该对象做处理。
        2. Vue3 并没有把所有的响应式代理都换成 Proxy .针对 ref() 创建的响应式数据的情况，它内部还是使用的 Object.definedProperty()
          function ref(value) {
            // 创建一个对象
            const obj = {}
            // 通过 Object.defineProperty()
            Object.defineProperty(obj, 'value', {
              get() {
                return value
              },
              set() {
                // 修改
              }
            })
            return obj
          }
        3. ref 数据在 js 逻辑上，要读取与赋值的话，必须 .value 。在模板中使用无须 .value 会自动解包

 -->

<template>
  <div>
    <h1>App</h1>
    <p>person.name: {{ person.name }}</p>
    <p>person.age: {{ person.age }}</p>
    <p>person.address.city: {{ person.address.city }}</p>
    <button @click="person.name = person.name + '~'">修改它</button>
    <button @click="person.age++">修改它</button>
    <button @click="person.address.city += '!'">修改它</button>
    <button @click="fn1">直接修改</button>
  </div>
</template>

<script>
import { reactive, ref } from 'vue'

export default {
  setup() {
    let person = reactive({
      name: '张三',
      age: 18,
      address: {
        city: '深圳市',
      },
    })

    const list = reactive(['apple'])

    // const isShow = reactive(true)

    console.log('person', person)
    console.log('list', list)
    // console.log('isShow', isShow)

    const fn1 = () => {
      person = {
        name: '李四',
        age: 20,
        address: {
          city: '广州市',
        },
      }
    }

    // 创建一个 ref 数据
    const count = ref(10)
    // 创建一个 reactive 数据
    const state = reactive({ name: '张三', count })
    console.log('state', state)
    console.log('state.name', state.name) // '张三'
    console.log('state.count', state.count) // 认为是：{ value: 10 }，实际上：10 因为Vue这儿做了自动解包
    state.count++
    console.log(state.count) // 11
    console.log(count.value) // 11

    count.value++
    console.log(state.count) // 12
    console.log(count.value) // 12

    const msg = ref('Vue3')
    const state1 = reactive([msg])
    console.log('state1[0]', state1[0]) // 这种情况不会自动解包，得到的是 RefImpl 类型的数据

    const ref1 = ref(10)
    console.log(ref1) // { value: 10 }
    const ref2 = ref({ name: '张哇', age: 18 })
    console.log(ref2) // { value: Proxy{name: '张哇', age: 18} }

    return {
      person,
      fn1,
    }
  },
}
</script>
